fix(daemon): harden local API against CSRF and DNS rebinding#243
Merged
Conversation
Contributor
|
🎉 PR Validation ✅ PASSED Commit: Checks:
Ready to merge! ✨ 🔗 View workflow run |
vreshch
marked this pull request as ready for review
July 7, 2026 22:09
vreshch
added a commit
that referenced
this pull request
Jul 7, 2026
## What README overhaul plus a hand-authored architecture diagram, aligned to master after #238-#245. Ready as the npm landing page. Touches only `README.md` and `docs/**` - no `src/`, `package.json`, or workflows. ## Changes - **`docs/architecture.svg`** - hand-written SVG (no render tooling). Neutral background with dark text on light boxes, so it reads in both light and dark GitHub themes and on npm. Shows AI tools -> MCP (stdio `agentage mcp` + daemon HTTP `/mcp` on `127.0.0.1:4243`) -> CLI + local daemon (single writer) -> local vaults (git-per-vault, `@agentage/memory-core`) -> sync out to git remotes and account sync (labeled protocol-neutrally, no internal tech named). - **`README.md`** restructured for a first-time reader: What is this -> Install -> Quickstart (local-only first, then optional `agentage setup`) -> Architecture (diagram) -> Command reference -> Sync -> MCP integration -> Daemon -> Env vars -> Development. - **`docs/architecture.md`** - short walk-through of the diagram. ## Reality-check vs master Built the CLI (`npm run build`) and verified every command and flag against the live `--help` output. Corrected drift from the merged PRs: - `vault add` now defaults to an **account** vault; `--local [path]`, `--git <remote>`, `--path <dir>` are the alternatives. - `vault sync [name]` now covers git and the account channel; progress prints per vault. - Documented the `update` command and `--no-daemon` global flag. - Daemon section notes the loopback-only, token-guarded, cross-origin-rejecting API and port-in-use reporting (#243, #244). - Friendly memory errors + non-zero exits (#240); 64 KB read clamp and secret refusal. - Describes no specific `src/` file paths (a sibling PR is moving `src/sync/` paths). ## Verification - `npm run verify` green: 405 unit tests pass, type-check + lint + format:check + build clean. - Ran the offline quickstart end-to-end against the built `dist/cli.js` (vault add --local, write via stdin, list, search, read `@vault/path`) - all pass. - Rendered `docs/architecture.svg` to PNG and eyeballed legibility. Note: `format:check` only globs `{src,e2e}/**/*.ts`, so it does not lint markdown; README changes are prose-only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds layered web-origin defense to the local daemon (127.0.0.1:4243) - previously any website could POST text/plain JSON to the mutating
/api/*routes (no CORS preflight), and DNS rebinding additionally unlocked reads plus the MCP surface.127.0.0.1:<port>,localhost:<port>,[::1]:<port>(the actually-bound port); else 403./api/*requiresContent-Type: application/json(415 otherwise) so browser simple-requests cannot reach handlers./mcptransport:enableDnsRebindingProtection: true+allowedHostspinned to the loopback host:port set (SDK 1.29.0 option surface).X-Agentage-Tokenfor/api/*. DaemonClient reads it per call; a missing/stale token makes the daemon count as unreachable (falls back to the in-process DirectClient). Cleaned up wherever pid/port files are cleaned./healthstays tokenless (probe path) but is still Host-validated;/mcpstays tokenless so editor MCP clients keep working, protected by the Host/Origin/DNS-rebinding layers.Why
The loopback socket was trusted implicitly - a malicious web page or another local process could drive memory writes/edits/deletes and sync. These layers close CSRF, DNS-rebinding, and same-machine cross-process access.
Scope notes
src/daemon/server-security.test.ts(avoids a sibling PR test file).daemon-entry.tstouched only to write/clean the token beside pid/port (a sibling PR owns the cleanup race)./api/sync/statusnow sends the token.Verified: npm run verify green locally.